home *** CD-ROM | disk | FTP | other *** search
- /*
- DX Clock.c
- 13 août 1991
- Stephan Burlot 1991
-
- Draw a clock in the menu bar.
-
- we use DrawString instead of multiple calls to DrawChars because some fonts are
- kerned and if we use DrawChar in srcCopy, it erases the right side of the previous
- char.
-
- we should calculate the clock's rect every time. (It would be cleaner to do so !)
-
- history :
-
- v1.0 13 Aout 1991 patches SystemTask
- v1.1 29 août 1991 patches JGNEFilter and DrawMenuBar
- save the clipping rgn
- detect double click
- about window
- v1.2 8 septembre 1991
- added ShowIcon
-
-
- released in the public domain January 5 1994
-
-
- */
- /*#include <color.h> */ /* some info about color quickdraw */
-
-
-
- #define KeypadMap 0x017C ; bitmap for numeric pad-18bits [long]
- #define KeyMap 0x0174 ; bitmap of the keyboard [2 longs]
- #define DoubleTime 0x02F0 ; double click ticks [long]
- #define RowBits 0x0C20 ; pixels horizontally
- #define ColLines 0x0C22 ; (word) screen vertical pixels
- #define WWExist 0x08F2 ; Window Manager Initialized ?
- #define WMgrCPort 0x0D2C ; [GLOBAL VAR] window manager color port
- #define WMgrPort 0x09DE ; Window Manager Port
- #define SystemTask 0xA9B4 ; System Task trap number
- #define GetNextEvent 0xA970 ; GetNextEvent trap number
- #define DrawMenuBar 0xA937 ; DrawMenuBar trap number
- #define Unimplemented 0x9F ; Unimplemented trap number
- #define MBState 0x0172 ; Mouse Button state
- #define Mouse 0x0830 ; mouse loc
- #define FractEnable 0x0BF4 ; fractionnal width allowed ? (byte)
- #define MenuList 0x0A1C ; menu list
- #define MBTicks 0x016E ; tick count @ last mouse button [long]
- #define MenuCInfo 0x0D50 ; handle to Menu Color Info
- #define RGBBlack 0x0C10 ; RGB color black
- #define RGBWhite 0x0C16 ; RGB Color white
- #define ChunkyDepth 0x0D60 ; [GLOBAL VAR] depth of the pixels
- #define JGNEFilter 0x029A ; address of tail patch to GetNextEvent
-
- #define mctRGB1 0x4
- #define mctRGB4 0x16
-
- #define JMP 0x4EF9
- #define JSR 0x4EB9
-
- #define tnam 0
- #define pointer 4
- #define font 8
- #define size 10
- #define offset 12
- #define stringwid 14
- #define vpos 16
- #define red 18
- #define green 20
- #define blue 22
- #define therect 24
- #define toprect 24
- #define leftrect 26
- #define bottomrect 28
- #define rightrect 30
- #define useclockcolor 31
- #define timewithsecs 32
-
- pascal void ShowINIT() ;
-
- void Main(void) ;
-
- void main()
-
- {
- asm {
-
- move.l D4,-(SP) ; save D4 on stack
-
- tst.b MBState ; mouse button down ?
- bpl @noPatch ; yes, dont install patch
-
- lea JGNEFilter,A0
- lea @exitST,A1
- move.l (A0),(A1) ; save the previous contents of JGNEFilter into exitST
-
- lea @lasttime,A0 ; init the last time
- move.l Time,(A0)
-
- lea @sysenvrec,A0 ; check the current system version
- move.w #1,D0
- _SysEnvirons
-
- lea @hascolor,A1 ; do we have color QD ?
- move.b 9(A0),(A1)
-
- move.w 4(A0),D0 ; system version is in D0
- cmp.w #0x700,D0 ; system seven ?
- bmi.s @system6 ; no
- move.w #65,D2 ; subtract width of two menus at top right corner
- bra.s @goon
- @system6
- move.w #20,D2 ; subtract width of on cue at top right corner
- @goon
-
- subq #4,SP ; space for handle
-
- move.l #'DXCL',-(SP) ; GetResource('DXCL',1)
- move.w #0x1,-(SP)
- _GetResource
-
- move.l (SP)+,A2 ; put handle to resource into A2
- move.l A2,D3 ; save a copy of the resource handle into D3
- movea.l (A2),A2 ; dereference handle.
-
- lea @last,A0 ; calculate size of patch
- lea @ThePatch,A1
- suba.l A1,A0
- move.l A0,D0
- move.l D0,D4 ; save D4 for BlockMove
- _NewPtr SYS ; allocate ptr in system heap /D0 used
- bne.s @noPatch ; if error, exit
-
- lea JGNEFilter,A1
- move.l A0,(A1) ; set address of JGNEFilter to our patch
-
- move.l A0,-(SP) ; save ptr onto heap
-
- move.w #DrawMenuBar,D0 ; get the address of the trap
- _GetTrapAddress ; result is in A0
-
- lea @exitDM,A1
- move.l A0,(A1) ; save the address of trap into exitDM
-
- lea @ThePatch,A0
- move.l (SP),A1
- move.l D4,D0
- _BlockMove ; move the patch code into the system heap, A0/A1/D0 used
-
- lea @drawmenubarpatch,A0 ; calculate address of drawmenubarpatch
- lea @ThePatch,A1
- suba.l A1,A0 ; offset of drawmenubarpatch from beginning of patch
- adda.l (SP),A0 ; add address of patch in sysheap. A0 contains the dest address
- move.w #DrawMenuBar,D0 ; set the address of the trap
- _SetTrapAddress
-
- lea @datarec,A0 ; calculate offset of datarec from beginning of patch
- lea @ThePatch,A1
- suba.l A1,A0 ; offset of datarec from beginning of patch
- adda.l (SP)+,A0 ; add address of patch in sysheap. A0 contains the dest address
- move.l A0,A1 ; put A0 into A1 for BlockMove (A1 is dest address)
-
- move.l A0,pointer(A2) ; store ptr to data into the resource
- move.w D2,offset(A2) ; store offset into the resource
-
- move.l A2,A0
- move.l #34,D0 ; rec is 34 bytes long
- _BlockMove
-
- move.l D3,-(SP) ; save back the resource, because we've changed the pointer value
- move.l (SP),-(SP)
- _ChangedResource
- _WriteResource
-
- move.w #128,-(SP) ; draw icon
- move.w #-1,-(SP) ; advance position
- bsr ShowINIT
- bra.s @exit
-
- @noPatch ; no patch, exit
-
- move.w #128,-(SP) ; draw icon
- move.w #0,-(SP) ; dont advance position
- bsr ShowINIT
-
- move.w #127,-(SP) ; draw cross
- move.w #-1,-(SP) ; and advance position
- bsr ShowINIT
-
- @exit
- move.l (SP)+,D4
-
- rts
-
- @sysenvrec ; record filled by _SysEnvirons
- DC.W 0
- DC.W 0
- DC.W 0
- DC.W 0
- DC.B 0
- DC.B 0
- DC.W 0
- DC.W 0
- DC.W 0
-
- ;************************* the patch *********************************************/
-
- #define saveport -4
- #define saveclip -8
- #define local1 saveclip
- @ThePatch
-
- bsr.s @doclock ; do it, joe
- dc JMP
- @exitST ; here comes the address of the original JGNEFilter
- nop
- nop
-
- @drawmenubarpatch ; tail patch to DrawMenuBar
-
- dc JSR
- @exitDM ; here comes the address of the original patch
- nop
- nop
-
- link A6,#local1
-
- movem.l D0-D4/A0-A2,-(SP) ; save some registers
- moveq #0,D3 ; D3:Boolean : draw the date ?
- bra.s @drawdate
-
- @doclock
-
- link A6,#local1
-
- movem.l D0-D4/A0-A2,-(SP) ; save some registers
-
- tst.b WWExist ; Window Manager initialized ?
- bne @goodbye ; No : exit
- tst.w MBarHeight ; is there a menu bar ?
- beq @goodbye ; No : exit
-
- moveq #0,D3 ; D3:Boolean : draw the date ?
-
- cmp.w #mouseDown,OFFSET(EventRecord,what)(A1) ; is it a mouse down ?
- bne.s @drawtime ; no, continue
-
- subq #2,sp ; space for result
- move.l OFFSET(EventRecord,where)(A1),-(SP) ; push the point
- pea @therect ; push the rect
- _PtInRect
- move.b (SP)+,D3
-
- beq.s @drawtime ; Pt is not in rect, so draw the time
-
- lea @oldpoint,A0
- move.l (A0)+,D0 ; last click pos is in D0
- move.l (A0),D1 ; last click time is in D1
-
- lea @oldpoint,A0
- move.l OFFSET(EventRecord,where)(A1),(A0)+ ; save the point
- move.l Ticks,(A0) ; save the time
-
- cmp.l OFFSET(EventRecord,where)(A1),D0 ; same point as previous click ?
- bne.s @drawdate ; no
- move.l Ticks,D0 ; time between clicks < DoubleTime ?
- sub.l D1,D0
- cmp.l DoubleTime,D0
- bgt.s @drawdate ; no, exit
-
- bsr @doabout
-
- @notdblclick
-
- ; move.w OFFSET(EventRecord,modifiers)(A1),D0
- ; btst #11,D0
- ; beq.s @drawdate
- ; lea @hidden,A0
- ; not (A0)
- ; beq.s @drawtime
-
- ; move.l WMgrPort,-(SP) ; sets the port to the window manager port
- ; _SetPort
- ; pea @therect
- ; _EraseRect ; erase the clock rect.
-
- @drawtime
-
- move.l @lasttime,D1 ; should we draw the time ?
- cmp.l Time,D1
- bge @goodbye ; no, exit
-
- @drawdate
-
- ; move.w @hidden,D0
- ; bne @goodbye
-
- move.w @leftrect,D0
-
- move.l MenuList,A0 ; we can draw the time if there is no menu on the clock's rect
- move.l (A0),A0
- move.w 2(A0),D1 ; 2(A0) holds the right coord of last menu
- cmp.w D0,D1 ; D0 holds the left coord of the clock's rect
- bgt @goodbye ; sorry, can't do that
-
- pea saveport(A6) ; saves the current port
- _GetPort
-
- move.l #0x000A0014,D4 ; initialize counter. point (10,20)
-
- move.w @hascolor,D0 ; are we in color ?
- bne @initcolor
-
- ; ************************* init things for BW machine ********************
-
- move.l WMgrPort,-(SP) ; sets the port to the window manager port
- _SetPort
-
- @t1 subq #2,-(SP) ; test if a screen saver is active (stolen from SuperClock)
- move.l D4,-(SP)
- _GetPixel ; works in the local port
- tst.b (SP)+
- dbeq D4,@t1
- bne @endrestore
-
- move.l WMgrPort,A0 ; A0 holds a pointer to the window manager port
-
- move.w OFFSET(GrafPort,txFont)(A0),-(SP) ; save some params on the stack
- move.w OFFSET(GrafPort,txSize)(A0),-(SP)
- move.w OFFSET(GrafPort,txMode)(A0),-(SP)
- bra.s @endinit
-
- @initcolor ; ************************* init things for color machine ********************
-
- move.l WMgrCPort,-(SP) ; sets the port to the color window manager port
- _SetPort
-
- @t2
- subq.w #6,SP ; test if a screen saver is active (stolen from SuperClock)
- move.l D4,-(SP)
- pea 4(SP)
- _GetCPixel ; works in the local port
- move.w (SP)+,D0
- or.w (SP)+,D0
- or.w (SP)+,D0
- dbne D4,@t2
- beq @endrestore
-
- move.l WMgrCPort,A0 ; A0 holds a pointer to the color window manager port
-
- move.w OFFSET(CGrafPort,txFont)(A0),-(SP) ; save some params on the stack
- move.w OFFSET(CGrafPort,txSize)(A0),-(SP)
- move.w OFFSET(CGrafPort,txMode)(A0),-(SP)
- lea @savedFGcolor,A1
-
- move.l OFFSET(CGrafPort,rgbFgColor)(A0),(A1)+ ; save the foreground color
- move.l OFFSET(CGrafPort,rgbFgColor+4)(A0),(A1)+
- move.l OFFSET(CGrafPort,rgbFgColor+8)(A0),(A1) ; save the background color
-
- /* the lines above were originally :
-
- move.l OFFSET(CGrafPort,rgbFgColor)(A0),(A1)+ ; save the foreground color
- move.w OFFSET(CGrafPort,rgbFgColor+4)(A0),(A1)+
- move.l OFFSET(CGrafPort,rgbBkColor)(A0),(A1)+ ; save the background color
- move.w OFFSET(CGrafPort,rgbBkColor+4)(A0),(A1)
-
- so I've saved 8 bytes !
- */
- move.l #RGBWhite,-(SP) ; push default colors on the stack
- move.l #RGBBlack,-(SP)
-
- move.w ChunkyDepth,D0 ; if we are in one bit mode,
- subq.w #1,D0
- beq.s @setcolor ; don't use MCInfo
-
- move.l MenuCInfo,A0
- move.l (A0),A0
- cmp.w #-99,(A0) ; item id is -99 if there is no MC entry
- beq.s @noMCentry
-
- lea mctRGB1(A0),A1 ; push foreground color
- move.l A1,(SP)
-
- lea mctRGB4(A0),A1 ; push background color
- move.l A1,4(SP)
-
- @noMCentry
- move.b @useclockcolor,D0 ; if we should use the clock's color
- beq.s @setcolor
- lea @thecolor,A1
- move.l A1,(SP)
- @setcolor
- _RGBForeColor ; set the foreground & background color
- _RGBBackColor
-
- @endinit
-
- subq #4,SP ; allocate some space on the stack
- _NewRgn ; create a new rgn
- move.l (SP),saveclip(A6) ; save the handle into saveclip
- _GetClip ; get the current clipping rgn
- pea @therect
- _ClipRect ; set the clipping region.
-
- move.w @leftrect,-(SP)
- move.w @vpos,-(SP) ; v coord
- _MoveTo
-
- move.w @font,-(SP) ; set the font, size & mode
- _TextFont
- move.w @size,-(SP)
- _TextSize
- clr.w -(SP) ; srcCopy is 0
- _TextMode
-
- lea @DateTimeRec,A0 ; converts the date & time to num
- move.l Time,D0
- _Secs2Date
-
- lea @loop,A1 ; let's do some self modifying code !
- move.w #':',2(A1) ; use ':' to draw the time
- lea @a,A1
- move.w #0x3018,(A1) ; move.w (A0)+,D0
- tst.b D3
- beq.s @addoffset
-
- sub.w #1900,(A0) ; wont work in the 21th century !
- lea @loop,A1
- move.w #'.',2(A1) ; use '.' to draw the date
- lea @a,A1
- move.w #0x3020,(A1) ; move.w -(A0),D0
- @addoffset
- addq.w #6,A0 ; A0+6 points to the time
- lea @thestring,A1
- move.b #9,(A1)+ ; the string is 9 bytes long
-
- moveq #02,D2 ; loop 3 times
- bra.s @loop1 ; skip ':' at start
- @loop
- move.b #':',(A1)+ ; this line can be modified by the code above
- @loop1
- moveq #0,D0
- @a move.w (A0)+,D0
- divu.w #10,D0
- or.b #0x30,D0 ; ASCII('0') is 0x30
- move.b D0,(A1)+
- swap D0
- or.b #0x30,D0 ; ASCII('0') is 0x30
- move.b D0,(A1)+
- dbf D2,@loop
-
- tst.b D3
- bne.s @drawit
- move.b @useclockcolor+1,D0 ; should we include the secs ?
- bne.s @drawit ; no, draw the time
- lea @thestring,A1 ; set
- move.b #5,(A1)
- @drawit
- pea @thestring
- _DrawString ; draw the string
-
- move.l saveclip(A6),-(SP) ; restore the clipping rgn
- move.l (SP),-(SP)
- _SetClip
- _DisposeRgn ; dispose the save clip rgn
-
- _TextMode ; restore things
- _TextSize
- _TextFont
- move.w @hascolor,D0
- beq.s @endrestore
-
- @restorecolor
-
- pea @savedFGcolor ; restore the foreground & background colors
- _RGBForeColor
- pea @savedBKcolor
- _RGBBackColor
-
- @endrestore
-
- move.l saveport(A6),-(sp) ; restore current port
- _SetPort
-
- lea @lasttime,A0
- move.l Time,(A0)
- tst.b D3
- beq.s @goodbye
- add.l #3,(A0) ; set the next time to 3 secs ahead
-
- @goodbye
-
- movem.l (SP)+,D0-D4/A0-A2 ; restore registers
- unlk A6
- rts ; back to caller
-
- @doabout ; ************************* aboutwindow *********************************
-
- #define boundsrect -8
- #define thewindow -12
- #define saved -16
- #define locals saved
-
- link A6,#locals
- movem.l A0-A3/D0-D3,-(sp) ; save some regs
-
- pea saved(A6) ; save current port
- _GetPort
-
- lea boundsrect(A6),A0 ; center window in screen
- move.w ColLines,D0 ; pixels vert.
- sub.w #0xC8,D0
- lsr.w #1,D0
- swap D0 ; top coord in high byte of D0
- move.w RowBits,D1
- sub.w #0xC8,D1
- lsr.w #1,D1
- move.w D1,D0 ; left coord in low byte of D0
- move.l D0,(A0)+
- add.l #0x00C800C8,D0
- move.l D0,(A0)
- subq #4,SP ; result (windowPtr)
- clr.l -(sp) ; wStorage (nil)
- pea boundsrect(a6) ; boundsrect
- clr.l -(sp) ; title ??
- move.b #1,-(sp) ; visible
- move.w #dBoxProc,-(sp) ; proc id
- move.l #-1,-(sp) ; behind
- clr.w -(sp) ; go away flag
- clr.l -(sp) ; refcon
- _NewWindow
- move.l (sp),thewindow(A6) ; result (windowPtr)
- _SetPort
-
- clr.l -(sp) ; textfont(0), textsize(0)
- _TextFont
- _TextSize
- subq #2,SP ; result (word)
- pea @str1
- _StringWidth
- move.w (sp)+,D0
- move.w #0xC8,D1
- sub.w D0,D1
- lsr.w #1,D1
- move.w D1,-(sp) ; horizontal coord of string (centered in window)
- move.w #20,-(sp)
- _MoveTo
- pea @str1
- _DrawString ; draw the string
-
- move.w #geneva,-(sp) ; textfont(geneva)
- _TextFont
- move.w #9,-(sp) ; textsize(9)
- _TextSize
-
- lea boundsrect(a6),A0
- move.l #0x00500005,(A0)+
- move.l #0x00C300C3,(A0)
- pea boundsrect(A6)
- _FrameRect
- pea boundsrect(A6)
- move.l #0x00020002,-(sp)
- _InsetRect
- pea @str2 ; pointer to the string
- lea @endstr2,A0 ; calculate length of string
- lea @str2,A1
- suba.l A1,A0
- move.l A0,-(sp) ; length of string (long)
- pea boundsrect(A6) ; the rect
- move.w #teJustCenter,-(sp) ; centered
- _TextBox
-
- move.l Ticks,D0
- add.l #30,D0
-
- move.w #1,-(sp)
- _SysBeep
-
- @wait
- cmp.l Ticks,D0
- bpl.s @wait
- move.l KeyMap,D0
- move.l KeyMap+4,D1
- move.l KeypadMap,D2
- @no tst.b MBState ; wait til button
- bpl.s @aboutend
- cmp.l KeyMap,D0
- bne.s @aboutend
- cmp.l KeyMap+4,D1
- bne.s @aboutend
- cmp.l KeypadMap,D2
- beq.s @no
-
- @aboutend
-
- move.l #0x0000FFFF,D0
- _FlushEvents
-
- move.l thewindow(A6),-(sp) ; kill the window
- _DisposeWindow
-
- move.l saved(A6),-(sp) ; restore grafport
- _SetPort
-
- movem.l (sp)+,A0-A3/D0-D3 ; restore regs
- unlk A6
- rts
-
- ; the strings !!
-
- @str1
- DC.B 8,'D','X',' ','C','l','o','c','k'
- @str2
- DC.B 'b','y',' ','S','t','e','p','h','a','n',' ','B','u','r','l','o','t'
- DC.B 13,13
- DC.B 'D','X',' ','C','l','o','c','k',' ','i','s',' ','f','r','e','e',' ','!'
- DC.B 13,13
- DC.B '©',' ','C','o','r','i','o','l','i','s'
- DC.B 13,13,13,13
- DC.B 'p','r','e','s','s',' ','m','o','u','s','e',' ','b','u','t','t','o','n',' ','t','o',' '
- DC.B 'c','o','n','t','i','n','u','e','.'
- @endstr2
-
- ;@hidden DC.W 0 ; is the clock hidden
- @oldpoint DC.L 0 ; last point click
- @oldticks DC.L 0 ; last click time
-
- @savedFGcolor DC.W 0 ; saved foreground color for CGrafPort
- DC.W 0
- DC.W 0
- @savedBKcolor DC.W 0 ; saved background color for CGrafPort
- DC.W 0
- DC.W 0
-
- @DateTimeRec ; holds the converted date & time
-
- @year DC.W 0
- @month DC.W 0
- @day DC.W 0
- @hour DC.W 0
- @minute DC.W 0
- @second DC.W 0
- @dayOfW DC.W 0
-
- @thestring DC.L 0 ; thestring holds the time. 10 bytes long.
- DC.L 0
- DC.W 0x0020 ; last char is always a space.
-
- @lasttime DC.L 0 ; last time we've drawn the clock
-
- @hascolor DC.W 0 ; has color QD ?
-
- @datarec ; we store the handle 'DXCL' here
-
- @tnam DC.L 0 ; identifier of the resource
- @pointer DC.L 0 ; loc of the ptr
- @font DC.W 0 ; font used
- @size DC.W 0 ; size of the font
- @offset DC.W 0 ; offset from left
- @stringwid DC.W 0 ; width of time
- @vpos DC.W 0 ; v coordinate
- @thecolor
- @red DC.W 0 ; red color
- @green DC.W 0 ; green color
- @blue DC.W 0 ; blue color
-
- @therect ; rect used for clipping & drawing
- @toprect DC.W 0
- @leftrect DC.W 0
- @bottomrect DC.W 0
- @rightrect DC.W 0
- @useclockcolor DC.B 0,0 ; use clock's color instead of menu bar's
- ;@timewithsecs DC.B 0 ; draw the time with seconds
-
- @last
- }
- }
-